package lang

import (
	"gvm/native/basic"
	"gvm/rtda"
	"unsafe"
)

func RegisterObject() (className string, methods []*basic.NaMethod) {
	return "java/lang/Object", []*basic.NaMethod{
		{
			"getClass",
			"()Ljava/lang/Class;",
			getClass,
		}, {
			"hashCode",
			"()I",
			hashCode,
		}, {
			"clone",
			"()Ljava/lang/Object;",
			clone,
		},
	}
}

// public final native Class<?> getClass();
func getClass(jFrame *rtda.JFrame) {
	this := jFrame.LocalVars().GetThis()
	class := this.Class().JClass()
	jFrame.OperandStack().PushRef(class)
}

// public native int hashCode();
func hashCode(jFrame *rtda.JFrame) {
	this := jFrame.LocalVars().GetThis()
	hash := int32(uintptr(unsafe.Pointer(this)))
	jFrame.OperandStack().PushInt(hash)
}

// protected native Object clone() throws CloneNotSupportedException;
func clone(jFrame *rtda.JFrame) {
	this := jFrame.LocalVars().GetThis()
	loader := this.Class().GetClassLoader()
	cloneable := loader.LoadClass("java/lang/Cloneable")
	if !this.Class().IsImplements(cloneable) {
		panic("java.lang.CloneNotSupportedException")
	}
	jFrame.OperandStack().PushRef(this.Clone())
}
